class Simple_handler :
    def create_bus (self, **args):
        print "create_bus", args
    def create_bus_queue (self, **args):
        print "create_bus_queue", args
    def create_jms_queue (self, **args):
        print "create_jms_queue", args
    def create_jms_as (self, **args):
        print "create_jms_as", args
    def create_jms_factory (self, **args):
        print "create_jms_factory", args
    def create_mq_queue (self, **args):
        print "create_mq_queue", args
    def create_mq_factory (self, **args):
        print "create_mq_factory", args
    def create_datasource (self, **args):
        print "create_datasource", args
    def create_authentification_alias (self, **args):
        print "create_authentification_alias", args
    def deploy_application (self, filename, **args):
        print "There is new application to be deployed to the server", filename
    def application_destination (self, server, node, **args):
        print "New destination", server, node
    def create_jdbc_adapter_as (self, event_table, datasource_jndi, poll_period, vendor="ORACLE", **args):
        print "New JDBC adapter AS"
    def string_binding (self, name, jndi, value):
        print "New String namespace binding", name, jndi, value
def update_dict (d, new_d):
    d.update(new_d)
    return d

class clear_arguments:
    def __init__(self, f, this = None):
        self.f = f
        self.this = this
    def __call__(self, *args, **argv):
        to_str = lambda s : s == None and s or str(s)
        new_args = map (lambda s, to_str = to_str, args = args : to_str(s), args)
        new_argv = reduce (lambda acc, key, argv = argv, to_str = to_str : update_dict(acc, {key : to_str(argv[key])}), argv.keys(), {})

        print "function name", self.f, new_args, new_argv
        if len(new_args) > 0:
            return self.f (*new_args, **new_argv)
        else:
            return self.f (**new_argv)

created_jndi = []

class proxy :
    def __init__(self, f, keyword):
        self.f = f
        self.keyword = keyword
    def __call__ (self, **argv):
        if self.keyword in argv.keys() and argv[self.keyword] in created_jndi:
            print "Proxied!"
        else:
            print self.f, argv
            self.f(**argv)
        if argv.get(self.keyword) not in created_jndi:
            created_jndi.append(argv.get(self.keyword))

class check_delete:
    def __init__ (self, f, entity_type, parent, entity_property):
        self.f = f
        self.type = entity_type
        self.parent = parent
        self.property = entity_property
    def get_parent (self):
        return self.parent
    def get_type ():
        ret
    def get_property ():
        pass
    def __call__ (self, *args, **argv):
        if is_delete(argv):
            (lambda s, entity_type = self.type, argv = argv, parent = self.parent, entity_property=self.property : findAndRemove (entity_type, [[s, argv[s]]], parent)) (entity_property)
        else:
            self.f(*args, **argv)

class save_configuration:
    def __init__(self, f):
        self.f = f
    def __call__ (self, **argv):
        self.f (**argv)
        save ()

def is_delete (args):
    return "action" in args.keys() and args["action"] == "delete"

name_proxy = lambda f : proxy(f, "name")
jndi_proxy = lambda f : proxy(f, "jndi")
as_jndi_proxy = lambda f : proxy(f, "as_jndi")
queue_proxy = lambda f : proxy(f, "queue")
jndi_name_proxy = lambda f : proxy(f, "jndi_name")
class WSAdmin_handler :
    app_destinations = []
    bus_queues = []

    def __init__ (self, node, server):
        self.node, self.server = node, server
        self.create_mq_queue = clear_arguments(self.create_mq_queue)
        self.get_node_id = clear_arguments(self.get_node_id)

        self.create_bus = save_configuration(clear_arguments(name_proxy(self.create_bus)))
        self.create_bus_queue = save_configuration(clear_arguments(queue_proxy(self.create_bus_queue)))
        self.create_jms_queue = save_configuration(clear_arguments(queue_proxy(self.create_jms_queue)))
        self.create_jms_as = save_configuration(clear_arguments(queue_proxy(self.create_jms_as)))
        self.create_jms_factory = save_configuration(clear_arguments(queue_proxy(self.create_jms_factory)))
        self.get_provider_id = clear_arguments(self.get_provider_id)

        self.create_mq_factory = save_configuration(clear_arguments(queue_proxy(self.create_mq_factory)))
        self.get_jdbc_provider_id = clear_arguments(self.get_jdbc_provider_id)
        self.create_datasource = save_configuration(clear_arguments(queue_proxy(self.create_datasource)))
        self.create_authentification_alias = save_configuration(clear_arguments(queue_proxy(self.create_authentification_alias)))
        self.deploy_application = save_configuration(clear_arguments(self.deploy_application))
        self.application_destination = save_configuration(clear_arguments(self.application_destination))
        self.create_jdbc_adapter_as = save_configuration(clear_arguments(self.create_jdbc_adapter_as))

    def get_node_id (self):
        return AdminConfig.getid("/Node:%(node)s"%{"node" : self.node})
    def get_server_id (self):
        return AdminConfig.getid("/Node:%(node)s/Server:%(server)s"%{"node" : self.node, "server" : self.server})

    def create_bus (self, name, **args):
        if is_delete (args):
            print "Integration bus", name, "is being removed..."
            deleteBus (name)
        else:
            print "New integration bus is being created...", name
            createSIBus ("none", self.node, self.server, name, self.get_node_id())
            for queue in self.bus_queues:
                print "New queue."
                queue()
            self.bus_queues = []

    def create_bus_queue (self, name, queue, **args):
        if is_delete (args):
            print "Queue", queue, "at", name, "is being deleted..."
            deleteSIBQueue (queue, name)
        else:
            print "New queue at", name, "bus is being created.", name
            self.bus_queues.append (lambda node = self.node, server = self.server, name=name, queue=queue :  createSIBQueue ("none", node, server, queue, name))

    def create_jms_queue (self, name, jndi, bus_queue, **args):
        if is_delete (args):
            print "JMS queue", name, "is being removed..."
            deleteSIBJMSQueue (name, self.get_node_id ())
        else:
            print "New JMS queue for", bus_queue, "is being created.", name
            createSIBJMSQueue (name, jndi, "", bus_queue, self.get_node_id())
            if hasattr(self, "jms_as_specification"):
                self.jms_as_specification()

    def create_jms_as (self, name, jndi, bus_name, as_jndi, **args):
        name = name + "AS"
        if is_delete (args):
            print "Activation Spec", name, "is being deleted..."
            deleteSIBJMSActivationSpec(name, "none", self.server)
        else:
            print "New activation specification for", jndi, "is being created."
            self.jms_as_specification = lambda name = name, jndi=jndi,bus_name=bus_name,as_jndi=as_jndi, self=self: createSIBJMSActivationSpec (name, as_jndi, jndi, "Queue", "", "", bus_name, self.get_server_id())

    def create_jms_factory (self, name, jndi_name, bus_name, **args):
        if is_delete (args):
            print "Connection factory", name, "is being deleted..."
            deleteSIBJMSConnectionFactory (name, "none", self.server)
        print "New JMS factory at", bus_name, "is being created.", name
        createSIBJMSConnectionFactory ("none", self.server, name, jndi_name, "", "", bus_name, "", self.get_node_id())
    
    def get_provider_id (self, name):
        return AdminConfig.getid("/Server:%s/JMSProvider:%s"%(self.server, name))

    def create_mq_queue (self, provider, name, jndi, mq_name, **args):
        if is_delete (args):
            print "MQ queue", name, "is being deleted..."
            deleteMQJMSQueue (self.get_provider_id (provider), jndi)
        else:
            print "New JMS for MQ", name, "queue is being created.", mq_name
            createMQJMSQueue (self.get_provider_id (provider), name, jndi, mq_name)
            return name

    def create_mq_factory (self, provider, name, jndi, manager, channel, host, port, **args):
        if is_delete (args):
            print "MQ connection factory", name, "is being deleted..."
            deleteMQConnectionFactory (self.get_provider_id (provider), jndi)
        else:
            print "New MQ connection factory is being created.", name
            createMQConnectionFactory(self.get_provider_id(provider), name, jndi, manager, channel, host, port)

    
    def get_jdbc_provider_id (self, provider):
        return AdminConfig.getid("/JDBCProvider:%s"%(provider,))

    def create_datasource (self, name, connection_string, jndi, provider, JAAS="", **args):
        if is_delete(args):
            print "Data source", name, "is being deleted..."
            deleteDataSource (self.get_jdbc_provider_id(provider), jndi)
        else:
            print "New Oracle datasource", connection_string, "is being created."
            createDataSource_ext (self.get_node_id(), "none", self.node, self.server, self.get_jdbc_provider_id(provider), name, "", jndi, 160, JAAS, "com.ibm.websphere.rsadapter.Oracle10gDataStoreHelper", "Oracle", "", "", URL=connection_string)

    def create_authentification_alias (self, name, username, password, **args):
        if is_delete (args):
            print "JAAS", name, "is being deleted"
            deleteJAAS (name)
        else:
            print "New authentification alias is being created", name, username, password
            createJAAS (str(name), str(username), str(password))

    def deploy_application (self, filename, **args):
        if is_delete (args):
            name = getApplicationName (filename)
            print "Application", name, "is being deleted..."
            deleteApplicationByName( name )
        else:
            print "There is new application to be deployed to the server", filename, self.app_destinations
            deployApplication (filename, self.app_destinations)
            self.app_destinations = []

    def application_destination (self, server, node, **args):
        self.app_destinations.append({'servername' : server, 'nodename' : node})

    def string_binding (self, name, jndi, value, **args):
        if is_delete (args):
            print "Namespace binding", name, "is being deleted..."
            deleteNamespaceBinding (name)
        else:
            print "Namespace binding", name, "is being created..."
            createNamespaceBinding (self.get_node_id(), name, jndi, value)

    def create_jdbc_adapter_as (self, adapter, name, jndi, event_table, datasource_jndi, poll_period, vendor="ORACLE", **args):
        if is_delete (args):
            print "Activation spec for JDBC adapter", name, "is being deleted..."
            deleteJ2CActivationSpec (jndi)
        else:
            print "Activation spec for JDBC adapter", name, "is being created..."
            createJ2CActivationSpec (adapter, name, jndi, eventTableName=event_table, DatabaseVendor = vendor, dataSourceJNDIName = datasource_jndi, pollPeriod = poll_period)
    
        
